home *** CD-ROM | disk | FTP | other *** search
/ Day Cry / Day Cry CD.bin / oh_towns / taropyon / splib / splib.lzh / PRG / LHX / HEADER.C < prev    next >
C/C++ Source or Header  |  1992-12-08  |  9KB  |  445 lines

  1. /***********************************************************
  2.         header.c -- handle headers
  3. ***********************************************************/
  4. #define MSDOS
  5. #define MYDOS 'M'
  6.  
  7. #include    "lh386.h"
  8.  
  9. #include    <stdio.h>
  10. #include    <io.h>
  11. #include    <dos.h>
  12. #include    <time.h>
  13. #include    <string.h>
  14. #include    <stdlib.h>
  15. #include    "lh.h"
  16. #include    "intrface.h"
  17. #include    "errmes.h"
  18.  
  19. #ifdef    __HIGHC__
  20. #    pragma    On(Align_labels);
  21. #    pragma    On(Char_default_unsigned)
  22. #endif
  23.  
  24. #define HDRwork      (uchar *)(work +  0)
  25. #define HDRsize      (uchar *)(work +  0)
  26. #define HDRwhole     (uchar *)(work +  0)
  27. #define HDRsum         (uchar *)(work +  1)
  28. #define HDRmethod     (uchar *)(work +  2)
  29. #define HDRpacked     (uchar *)(work +  7)
  30. #define HDRoriginal  (uchar *)(work + 11)
  31. #define HDRtime      (uchar *)(work + 15)
  32. #define HDRattr      (uchar *)(work + 19)
  33. #define HDRlevel     (uchar *)(work + 20)
  34. #define HDRfnlen     (uchar *)(work + 21)
  35. #define HDRfname     (uchar *)(work + 22)
  36. #define HDRdos         (uchar *)(work + 23)
  37. #define HDRextsize     (uchar *)(work + 24)
  38.  
  39. struct head hpb;
  40.  
  41. char        methodID[6] = "\0\0\0\0\0\0";
  42.  
  43. static ulong nextpos;
  44.  
  45. #ifdef MSDOS
  46. #ifndef __HIGHC__
  47. #define Convint(p) (*(int *)(p))
  48. #else
  49. #define Convint(p) (*(short *)(p))
  50. #endif
  51. #define Convlong(p) (*(long *)(p))
  52. #else
  53. #define Convint(p) (*(p) + ((unsigned)*((p) + 1) << 8))
  54. #define Convlong(p) (Convint(p) + ((ulong)Convint((p) + 2) << 16))
  55. #endif
  56.  
  57. #ifdef MSDOS
  58. #ifndef __HIGHC__
  59. #define Setint(p, q) (*(uint *)(p)=q)
  60. #else
  61. #define Setint(p, q) (*(ushort *)(p)=q)
  62. #endif
  63. #define Setlong(p, q) (*(ulong *)(p)=q)
  64. #else
  65. #define Setint(p, q) {uint a = q; (p)[0] = a; (p)[1] = a >> 8;}
  66. #define Setlong(p, q) {ulong a = q;                \
  67.             (p)[0] = a; (p)[1] = a >> 8;        \
  68.             (p)[2] = a >> 16; (p)[3] = a >> 24;}
  69. #define MAXNAMELEN 128
  70. #endif
  71.  
  72. void        inithdr(void)
  73. {
  74.     long        pos;
  75.     int         c, err;
  76.     char       *p;
  77.  
  78.     pos = 0;
  79.     while ((c = getc(file1)) >= 0)
  80.     {
  81.         pos++;
  82.         if (c == '-')
  83.         {
  84.             getc(file1);
  85.             getc(file1);
  86.             getc(file1);
  87.             if (getc(file1) == '-')
  88.             {
  89.                 nextpos = pos - 3;
  90.                 p = gethdr(&err);
  91.                 if (p)
  92.                 {
  93.                     free(p);
  94.                     nextpos = pos - 3;
  95.                     return;
  96.                 }
  97.             }
  98.             fseek(file1, pos, SEEK_SET);
  99.         }
  100.     }
  101.     return;
  102. }
  103.  
  104. /*******************************
  105.   calculate check-sum of header
  106. *******************************/
  107. static char calcsum(void *h)
  108. {
  109.     char       *p, *q, i;
  110.  
  111.     p = (char *) h + 2;
  112.     q = p + *(uchar *) h;
  113.     for (i = 0; p < q; p++)
  114.         i += *p;
  115.     return i;
  116. }
  117.  
  118. static void extheader(char *exthdr, int size)
  119. {
  120.     uchar       *p;
  121.  
  122.     p = (uchar *) exthdr + 1;
  123.     switch (*exthdr)
  124.     {
  125.         case 0:
  126.             hpb.headcrc = Convint(p);
  127.             hpb.crcpos = (char *) p;
  128.             if (size > 5)
  129.                 hpb.info = *(p + 2);
  130.             break;
  131.         case 1:
  132.             hpb.filename = (char *) p;
  133.             hpb.filenlen = size - 3;
  134.             break;
  135.         case 2:
  136.             hpb.pathname = (char *) p;
  137.             hpb.dirnlen = size - 3;
  138.             break;
  139.         case 0x40:
  140.             if (hpb.dos == MYDOS)
  141.             {
  142.                 hpb.attr = Convint(p);
  143.             }
  144.             break;
  145.     }
  146. }
  147.  
  148.  
  149. #define readarc(a,b) fread(a, 1, b, file1)
  150.  
  151. char       *gethdr(int *err)
  152. /***
  153.   *err = 0 : normal end of header
  154.        = 1 : not a header
  155. ****/
  156. {
  157.     char       *p;
  158.     int         namelen, extsize;
  159.     int         i;
  160.  
  161.     *err = 0;
  162.     hpb.crcpos = NULL;
  163.     memset(&hpb, 0, sizeof(struct head));
  164.     *HDRsize = 0;
  165.     fseek(file1, nextpos, SEEK_SET);
  166.     readarc(HDRwork, 21);
  167.     if (*HDRsize == 0)
  168.         return NULL;
  169.     hpb.headersize = (int) *HDRsize + 2;
  170.     strncpy((char *) hpb.method, (char *) HDRmethod, 5);
  171.     hpb.packed = hpb.skip = Convlong(HDRpacked);
  172.     hpb.original = Convlong(HDRoriginal);
  173.     hpb.level = *HDRlevel;
  174.     hpb.attr = *HDRattr;
  175.     hpb.dirnlen = 0;
  176.     switch (hpb.level)
  177.     {
  178.         case 0:
  179.         case 1:
  180.             hpb.dostime.u = Convlong(HDRtime);
  181.             hpb.utc = dos2unix(&hpb.dostime.s);
  182.             if (hpb.headersize < 22)
  183.                 return NULL;
  184.             readarc(HDRwork + 21, hpb.headersize - 21);
  185.             if (calcsum(HDRwork) != *HDRsum)
  186.             {
  187.                 if (*HDRwork == 0x1a)
  188.                     return NULL;/* for LArc & XMODEM */
  189.                 *err = 1;
  190.                 return NULL;
  191.             }
  192.             namelen = *HDRfnlen;
  193.             hpb.filenlen = namelen;
  194.             hpb.filename = hpb.pathname = (void *) HDRfname;
  195.             i = hpb.headersize - namelen;
  196.             if (i >= 24)
  197.             {
  198.                 hpb.filecrc = Convint(HDRfname + namelen);
  199.             } else
  200.             {
  201.                 hpb.level = -1;
  202.             }
  203.             if (i >= 25)
  204.             {
  205.                 hpb.dos = *(HDRfname + namelen + 2);
  206.             }
  207.             nextpos = ftell(file1) + hpb.skip;
  208.             if (hpb.level <= 0)
  209.             {
  210.                 strncpy((char *) (hpb.pathname = e_malloc(namelen + 1)),
  211.                         (char *) HDRfname, namelen);
  212.                 hpb.pathname[namelen] = '\0';
  213.                 hpb.filename = convdelim(hpb.pathname, DELIM);
  214.                 return hpb.pathname;
  215.             }
  216.             p = (char *) HDRwork + *HDRsize;
  217.             while ((extsize = Convint(p)) != 0)
  218.             {
  219.                 readarc(p + 2, extsize);
  220.                 extheader(p + 2, extsize);
  221.                 p += extsize;
  222.             }
  223.             i = p + 2 - (char *) HDRwork;
  224.             hpb.packed -= i - hpb.headersize;
  225.             hpb.headersize = i;
  226.             break;
  227.         case 2:
  228.             readarc(HDRwork + 21, (hpb.headersize = Convint(HDRwhole)) - 21);
  229.             hpb.utc = Convlong(HDRtime);
  230.             hpb.dos = *HDRdos;
  231.             p = (char *) HDRextsize;
  232.             while ((extsize = Convint(p)) != 0)
  233.             {
  234.                 extheader(p + 2, extsize);
  235.                 p += extsize;
  236.             }
  237.             hpb.filecrc = Convint(HDRfnlen);
  238.             nextpos = ftell(file1) + hpb.skip;
  239.             break;
  240.         default:
  241.             *err = 1;
  242.             return NULL;
  243.     }
  244.     if (hpb.crcpos)
  245.     {
  246.         Setint(hpb.crcpos, 0);
  247.         crc = 0;
  248.         if (calccrc(HDRwork, hpb.headersize) != hpb.headcrc)
  249.         {
  250.             *err = 1;
  251.             return NULL;
  252.         }
  253.         Setint(hpb.crcpos, hpb.headcrc);
  254.     }
  255.     namelen = hpb.dirnlen + hpb.filenlen;
  256.     p = e_malloc(namelen + 1);
  257.     hpb.pathname = strncpy(p, hpb.pathname, hpb.dirnlen);
  258.     hpb.filename = strncpy(p + hpb.dirnlen, hpb.filename, hpb.filenlen);
  259.     *(p + namelen) = '\0';
  260.     convdelim(hpb.pathname, DELIM);
  261.     return hpb.pathname;
  262. }
  263.  
  264. void        makehdr(void)
  265. {
  266.     int         namelen;
  267.     uchar       *p, *q;
  268.  
  269.     hpb.crcpos = NULL;
  270.     memcpy(HDRmethod, hpb.method, 5);
  271.     Setlong(HDRpacked, hpb.skip = hpb.packed);
  272.     Setlong(HDRoriginal, hpb.original);
  273.     *HDRattr = 0x20;
  274.     *HDRlevel = hpb.level;
  275.     q = (uchar *) hpb.filename;
  276.     if (hpb.level == 0)
  277.         q = (uchar *) hpb.pathname;
  278.     namelen = strlen((char *) q);
  279.     p = (uchar *) HDRfnlen;
  280.     if (hpb.level != 2)
  281.     {
  282. #ifndef MSDOS
  283.         if (namelen > MAXNAMELEN)
  284.         {
  285.             *p++ = 0;
  286.         } else
  287. #endif
  288.         {
  289.             *p++ = namelen;
  290.             strcpy((char *) p, (char *) q);
  291.             if (hpb.level == 0)
  292.                 convdelim((char *) p, pathdelim);
  293.             p += namelen;
  294.         }
  295.         hpb.dostime.s = *unix2dos(hpb.utc);
  296.         Setlong(HDRtime, hpb.dostime.u);
  297.     } else
  298.     {
  299.         Setlong(HDRtime, hpb.utc);
  300.     }
  301.  
  302.     p += 2;                     /* filecrc */
  303.     if (hpb.level == 0)
  304.     {
  305.         *HDRsize = (uchar *) p - HDRmethod;
  306.         hpb.headersize = (uchar *) p - HDRwork;
  307.         *HDRattr = hpb.attr;
  308.         *HDRsum = calcsum(HDRwork);
  309.         return;
  310.     }
  311.     *p = MYDOS;
  312.     p++;
  313.     *HDRsize = p - HDRwork;
  314.  
  315. /*
  316. |  filename header     |
  317. |   2 ext-header size  |
  318. |----------------------|
  319. |   1 0x01             |
  320. |   ? filename         |
  321. |----------------------|
  322. */
  323.     if (hpb.level == 2
  324. #ifndef MSDOS
  325.         || namelen > MAXNAMELEN
  326. #endif
  327.         )
  328.     {
  329.         hpb.filenlen = strlen(hpb.filename);
  330.         Setint(p, hpb.filenlen + 3);
  331.         p += 2;
  332.         *p++ = 1;
  333.         memcpy(p, hpb.filename, hpb.filenlen);
  334.         p += hpb.filenlen;
  335.     }
  336. /*
  337. |  dirname header      |
  338. |   2 ext-header size  |
  339. |----------------------|
  340. |   1 0x02             |
  341. |   ? dirname          |
  342. |----------------------|
  343. */
  344.     if (hpb.pathname != hpb.filename)
  345.     {
  346.         hpb.dirnlen = hpb.filename - hpb.pathname;
  347.         Setint(p, hpb.dirnlen + 3);
  348.         p += 2;
  349.         *p++ = 2;
  350.         convdelim(hpb.pathname, DELIM2);
  351.         memcpy(p, hpb.pathname, hpb.dirnlen);
  352.         p += hpb.dirnlen;
  353.         convdelim(hpb.pathname, DELIM);
  354.     }
  355. #ifdef MSDOS
  356. /*
  357. |  attribute header    |
  358. |   2 ext-header size  |
  359. |----------------------|
  360. |   1 0x40             |
  361. |   2 attribute        |
  362. |----------------------|
  363. */
  364.     if (hpb.attr != 0x20)
  365.     {
  366.         Setint(p, 5);
  367.         p += 2;
  368.         *p++ = 0x40;            /* ext-header type */
  369.         Setint(p, hpb.attr);
  370.         p += 2;
  371.     }
  372. #endif
  373.  
  374. /*
  375. |  common header       |
  376. |   2 ext-header size  |
  377. |----------------------|
  378. |   1 0x00             |
  379. |   2 header crc       |
  380. | ( 1 information )    |
  381. |----------------------|
  382. */
  383.     if (p != HDRwor